#pragma once
#include<string>
#include<queue>
#include<mutex>
#include<atomic>
#include<thread>
#include<memory>
#include<condition_variable>
#include<functional>
#include"public.hpp"
#include "connection.hpp"

using namespace std;
/*
连接池模块
*/

class ConnectionPool {
public:
	//获取连接池实例
	static ConnectionPool* getConnectionPool();
	//给外部提供接口，从连接池中获取一个可用的空闲连接，给用户一个智能指针并且自定义删除器，
	//这样用户使用完后，不需要再调用函数归还，而是出作用域后自动析构
	shared_ptr<Connection> getConnection();
private:
	ConnectionPool();

	bool loadConfigFile();
	//运行在独立的线程中，创建连接
	void produceConnectionTask();

	//扫描是否有连接超出空闲时间
	void scannerConnectionTask();

	//以下信息通常在配置文件中
	string _ip;
	unsigned short _port; //端口号 3306
	string _username;	
	string _password;
	int _initSize;		//连接池初始链接量
	int _maxSize;		//连接池最大链接量
	int _maxIdleTime;	//连接池最大空闲时间
	int _connectionTimeout;	//连接池获取链接的超时时间
	string _dbname;
	condition_variable cv;//条件变量用于连接生产线程和消费线程的通信

	queue<Connection*> _connectionQue; //存储mysql链接的队列
	mutex _queueMutex; 
	atomic_int _connectionCnt;//记录所创建的connection连接总数
};

